<!DOCTYPE html>
<html>
<head>
    <title>训练结果分析</title>
    <style>
        .button-wrapper-full {
    position: relative;
    width: 100%;
    max-width: 800px;
}

.tooltip-message {
    display: none;
    position: absolute;
    bottom: 110%;
    left: 50%;
    transform: translateX(-50%);
    background-color: #ffcdd2;
    color: #c62828;
    font-size: 12px;
    padding: 4px 10px;
    border-radius: 4px;
    white-space: nowrap;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    z-index: 10;
}

/* 仅当按钮被禁用且鼠标悬停时，显示提示 */
.progress-button:disabled:hover + .tooltip-message {
    display: block;
}

        #statusButton:disabled {
    background-color: #bdbdbd !important;
    cursor: not-allowed !important;
    animation: none !important;
}
        .status-container {
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 1000;
        }

        #statusButton {
            padding: 12px 24px;
            border: none;
            border-radius: 25px;
            font-size: 14px;
            cursor: default;
            transition: all 0.3s ease;
            box-shadow: 0 2px 8px rgba(0,0,0,0.15);
            background-color: #bdbdbd;
            color: #616161;
        }

        #statusButton.completed {
            background-color: #4CAF50;
            color: white;
            cursor: pointer;
            animation: pulse 1.5s infinite;
        }

        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }

        .confirm-dialog {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: #e3f2fd;
            padding: 25px;
            border-radius: 8px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
            border: 1px solid #90caf9;
            width: 320px;
            font-family: Arial, sans-serif;
        }

        .confirm-dialog p {
            margin: 0 0 20px 0;
            color: #1565c0;
            font-size: 16px;
            line-height: 1.5;
        }

        .dialog-buttons {
            display: flex;
            justify-content: flex-end;
            gap: 10px;
        }

        .dialog-buttons button {
            padding: 8px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.2s ease;
            font-size: 14px;
        }

        #cancelBtn {
            background-color: #e0e0e0;
            color: #616161;
        }

        #cancelBtn:hover {
            background-color: #bdbdbd;
        }

        #confirmBtn {
            background-color: #42a5f5;
            color: white;
        }

        #confirmBtn:hover {
            background-color: #1e88e5;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        body {
            margin: 0;
            padding: 0;
            height: calc(100vh - 20px);
            font-family: Arial, sans-serif;
            background-color: #f8f9fa;
            overflow: hidden;
        }

        .analysis-results-container {
            font-size: 14px;
            line-height: 1.4;
            height: 100%;
            padding: 8px;
            padding-bottom: 28px;
        }

        .results-title {
            font-size: 15px;
            font-weight: 600;
            padding: 6px 8px;
            background-color: #f5f5f5;
            border-radius: 3px;
            margin-bottom: 8px;
            display: inline-block;
        }

        #results-container {
            overflow-y: auto;
            height: calc(100% - 80px);
        }

        .file-container {
            margin-bottom: 8px;
            border: 1px solid #b0bec5;
            border-radius: 6px;
            padding: 8px;
            background-color: #f5f5f5;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
            transition: background-color 0.3s ease;
        }

        .file-container:hover {
            background-color: #e3f2fd;
            box-shadow: 0 4px 10px rgba(33, 150, 243, 0.2);
        }

        /* 修改重点区域 */
        .file-title {
            position: relative;
            padding: 8px 35px 8px 12px;
            background-color: #e0e0e0;
            border-radius: 4px;
            font-size: 14px;
            font-weight: 600;
            color: #212121;
            display: flex;
            align-items: center;
        }

        .title-content {
            display: flex;
            align-items: center;
            gap: 10px;
            flex-grow: 1;
        }

        .epoch-checkbox {
            width: 16px;
            height: 16px;
            cursor: pointer;
            accent-color: #42a5f5;
            flex-shrink: 0;
        }

        .toggle-indicator {
            cursor: pointer;
            user-select: none;
            transition: transform 0.2s;
            font-size: 12px;
            color: #616161;
        }

        .delete-btn {
            position: absolute;
            right: 12px;
            top: 50%;
            transform: translateY(-50%);
            color: #424242;
            font-size: 20px;
            cursor: pointer;
            transition: all 0.3s ease;
            background: none;
            border: none;
            padding: 0;
            margin: 0;
        }

        .delete-btn:hover {
            color: #f44336;
            transform: translateY(-50%) scale(1.2);
        }

        .metric-container {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 12px;
            padding: 12px;
        }

        .metric-item {
            background: white;
            padding: 16px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            transition: box-shadow 0.3s ease;
        }

        .metric-item:hover {
            box-shadow: 0 4px 8px rgba(0,0,0,0.15);
        }

        .metric-title {
            color: #424242;
            font-weight: 500;
            margin-bottom: 6px;
            font-size: 13px;
        }

        .metric-value {
            color: #212121;
            font-size: 1.4em;
            font-weight: bold;
            text-align: center;
        }

        .file-results {
            display: none;
            margin-top: 8px;
        }

        .progress-container {
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            height: 60px;
            background: #fff;
            border-top: 1px solid #e0e0e0;
            z-index: 1000;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0 20px;
        }

        .progress-button {
            position: relative;
            width: 100%;
            max-width: 800px;
            height: 44px;
            border: none;
            border-radius: 22px;
            background: #f5f5f5;
            overflow: hidden;
            cursor: default;
            transition: all 0.3s ease;
        }

        .progress-bar {
            position: absolute;
            left: 0;
            top: 0;
            height: 100%;
            width: 0;
            background: linear-gradient(90deg, #4CAF50 0%, #66BB6A 100%);
            transition: width 0.5s ease;
        }

        .progress-text {
            position: relative;
            z-index: 1;
            color: #616161;
            font-size: 18px;
            font-weight: 600;
            transition: color 0.3s ease;
            letter-spacing: 0.5px;
            text-shadow: 0 1px 2px rgba(0,0,0,0.1);
        }

        .progress-button.completed {
            background: #4CAF50;
        }
        .progress-button.completed .progress-text {
            color: white;
        }
        .progress-button.completed .progress-bar {
            display: none;
        }

        /* 新增的模型名称编辑样式 */
        .model-name {
            cursor: pointer;
            padding: 2px 4px;
            border-radius: 3px;
            transition: background-color 0.2s;
        }

        .model-name:hover {
            background-color: #e0e0e0;
        }

        .model-name-input {
            font-size: 14px;
            font-weight: 600;
            border: 1px solid #90caf9;
            border-radius: 3px;
            padding: 2px 4px;
            width: auto;
            min-width: 100px;
            outline: none;
        }
    </style>
</head>
<body>
<div class="analysis-results-container">
    <div class="results-title">训练指标监控</div>
    <div id="results-container">
        <!-- Epoch条目将在这里动态添加 -->
    </div>
</div>
<div class="progress-container" id="progressContainer">
    <div class="button-wrapper-full">
        <button class="progress-button" id="statusButton">
            <span class="progress-text">正在训练中 (0/0)</span>
            <span class="progress-bar"></span>
        </button>
        <div class="tooltip-message">请选择至少一个模型！</div>
    </div>
</div>


<!-- 删除确认对话框 -->
<div id="confirmDialog" class="confirm-dialog">
    <p>确定要删除这个Epoch记录吗？</p>
    <div class="dialog-buttons">
        <button id="cancelBtn">取消</button>
        <button id="confirmBtn">确定删除</button>
    </div>
</div>

<script>
    let currentFileToDelete = null;
    let currentEpoch = 0;
    let maxEpochs = 0;
    let isTrainingComplete = false;
    let lastEpochNumber = 0;
    let modelNames = {}; // 存储模型名称 {epoch: name}

    // 确认对话框处理
    function showConfirmDialog(fileElement) {
        currentFileToDelete = fileElement;
        document.getElementById('confirmDialog').style.display = 'block';
    }

    function hideConfirmDialog() {
        document.getElementById('confirmDialog').style.display = 'none';
    }

    function confirmDelete() {
        if (currentFileToDelete) {
            const epoch = currentFileToDelete.querySelector('.epoch-checkbox').dataset.epoch;
            delete modelNames[epoch];
            currentFileToDelete.remove();
            hideConfirmDialog();
            // 删除后更新按钮状态
            handleCheckboxChange();
        }
    }

    // 初始化按钮事件
    document.getElementById('confirmBtn').addEventListener('click', confirmDelete);
    document.getElementById('cancelBtn').addEventListener('click', hideConfirmDialog);

    // WebSocket连接
    const socket = new WebSocket('ws://' + window.location.host + '/ws/training-results/?page=trainresult');

    function updateStatusButton() {
        const button = document.getElementById('statusButton');
        const progressBar = button.querySelector('.progress-bar');
        const progress = maxEpochs > 0 ? (currentEpoch / maxEpochs) : 0;

        progressBar.style.width = `${Math.round(progress * 100)}%`;

        if (isTrainingComplete) {
            button.querySelector('.progress-text').textContent = '开始工作量估计！';
        } else {
            const percent = Math.round(progress * 100);
            button.querySelector('.progress-text').textContent =
                `训练中 (${currentEpoch}/${maxEpochs}) ${percent}%`;
        }
    }

    // WebSocket处理
    socket.onopen = function(e) {
        console.log("WebSocket连接已建立");
        updateStatusButton();
    };

    socket.onmessage = function(e) {
        try {
            const data = JSON.parse(e.data);

            switch(data.type) {
                case 'epoch_ready':
                    handleEpochReady(data);
                    break;

                case 'metrics_update':
                    handleMetricsUpdate(data);
                    break;

                case 'training_complete':
                    handleTrainingComplete(data);
                    break;

                default:
                    console.warn('未知消息类型:', data.type);
            }
        } catch(err) {
            console.error("消息解析错误:", err);
        }
    };

    // 处理模型名称编辑
    function handleModelNameEdit(event, epoch) {
        event.stopPropagation();
        const nameElement = event.target;
        const currentName = nameElement.textContent;

        // 创建输入框
        const input = document.createElement('input');
        input.type = 'text';
        input.className = 'model-name-input';
        input.value = currentName;

        // 替换文本为输入框
        nameElement.replaceWith(input);
        input.focus();

        // 保存编辑
        function saveEdit() {
            const newName = input.value.trim();
            const newNameElement = document.createElement('span');
            newNameElement.className = 'model-name';
            newNameElement.textContent = newName || `Epochs(${epoch})`;
            newNameElement.ondblclick = (e) => handleModelNameEdit(e, epoch);

            // 更新模型名称存储
            modelNames[epoch] = newNameElement.textContent;

            input.replaceWith(newNameElement);
            document.removeEventListener('click', outsideClick);
        }

        // 点击外部保存
        function outsideClick(e) {
            if (!input.contains(e.target)) {
                saveEdit();
            }
        }

        // 回车保存
        input.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                saveEdit();
            }
        });

        // 点击外部保存
        document.addEventListener('click', outsideClick);
    }

    // Epoch就绪处理
    function handleEpochReady(data) {
        const container = document.getElementById('results-container');
        const epoch = data.epoch;

        // 初始化模型名称
        modelNames[epoch] = `Epochs(${epoch})`;

        const newEpoch = document.createElement('div');
        newEpoch.className = 'file-container';
        newEpoch.innerHTML = `
            <div class="file-title" data-expanded="false">
                <span class="title-content">
                    <input type="checkbox"
                           class="epoch-checkbox"
                           data-epoch="${epoch}"
                           onclick="event.stopPropagation()"
                           onchange="handleCheckboxChange()">
                    <span class="toggle-indicator" onclick="toggleFileResults(this.parentElement.parentElement)">▼</span>
                    <span class="model-name" ondblclick="handleModelNameEdit(event, ${epoch})">Epochs(${epoch})</span>
                </span>
                <span class="delete-btn" onclick="event.stopPropagation(); showConfirmDialog(this.parentElement.parentElement)">×</span>
            </div>
            <div class="file-results" style="display: none"></div>
        `;
        container.appendChild(newEpoch);
        container.scrollTop = container.scrollHeight;
    }

    // 指标更新处理
    function handleMetricsUpdate(data) {
        currentEpoch = data.epoch;
        maxEpochs = data.max_epochs || maxEpochs;

        const epochElements = document.querySelectorAll('.file-container');
        const targetElement = Array.from(epochElements).find(el => {
            const checkbox = el.querySelector('.epoch-checkbox');
            return checkbox && parseInt(checkbox.dataset.epoch) === data.epoch;
        });

        if (targetElement) {
            const resultsContainer = targetElement.querySelector('.file-results');
            resultsContainer.innerHTML = `
                <div class="metric-container">
                    ${createMetricItem('MAE', '平均绝对误差', data.mae.toFixed(4))}
                    ${createMetricItem('MMRE', '平均相对误差', data.mmre.toFixed(4))}
                    ${createMetricItem('MdAE', '中位绝对误差', data.mdae.toFixed(4))}
                    ${createMetricItem('PRED', '预测准确率', `${data.pred.toFixed(2)}%`)}
                </div>
            `;

            const fileTitle = targetElement.querySelector('.file-title');
            if (fileTitle.getAttribute('data-expanded') === 'false') {
                toggleFileResults(fileTitle);
            }
        }

        updateStatusButton();
    }

    // 处理训练完成
    function handleTrainingComplete(data) {
        isTrainingComplete = true;
        currentEpoch = data.max_epochs || maxEpochs;
        maxEpochs = data.max_epochs || maxEpochs;
        lastEpochNumber = currentEpoch;
        updateStatusButton();

        // 自动选中最后一个epoch
        const lastCheckbox = document.querySelector(`.epoch-checkbox[data-epoch="${lastEpochNumber}"]`);
        if (lastCheckbox) {
            lastCheckbox.checked = true;
            handleCheckboxChange();
        }

        // 向父页面发送消息
        window.parent.postMessage({
            type: 'training_complete',
            status: 'done',
            max_epochs: maxEpochs
        }, '*');

        document.getElementById('statusButton').addEventListener('click', () => {
            const checkboxes = document.querySelectorAll('.epoch-checkbox');
            const selectedModels = Array.from(checkboxes)
                .filter(checkbox => checkbox.checked)
                .map(checkbox => {
                    const epoch = parseInt(checkbox.dataset.epoch);
                    return {
                        epoch: epoch,
                        name: modelNames[epoch] || `Epochs(${epoch})`
                    };
                });

            if (selectedModels.length > 0) {
                window.parent.postMessage({
                    type: 'start_prediction',
                    path: '/predict',
                    selected_models: selectedModels
                }, '*');
            }
        });
    }

    // 处理勾选变化
    function handleCheckboxChange() {
        const checkboxes = document.querySelectorAll('.epoch-checkbox');
        const selectedModels = Array.from(checkboxes)
            .filter(checkbox => checkbox.checked)
            .map(checkbox => {
                const epoch = parseInt(checkbox.dataset.epoch);
                return {
                    epoch: epoch,
                    name: modelNames[epoch] || `Epochs(${epoch})`
                };
            });

        if (socket.readyState === WebSocket.OPEN) {
            socket.send(JSON.stringify({
                type: 'epoch_selection',
                selected_models: selectedModels
            }));
        }

        updateButtonState(selectedModels.map(m => m.epoch));
    }

    // 更新按钮状态
    function updateButtonState(selectedEpochs) {
        const button = document.getElementById('statusButton');
        if (!isTrainingComplete) return;

        const lastEpochSelected = selectedEpochs.includes(lastEpochNumber);
        const hasOtherSelection = selectedEpochs.some(epoch => epoch !== lastEpochNumber);

        button.disabled = false;
        button.classList.add('completed');

        if (selectedEpochs.length === 0) {
            button.disabled = true;
            button.classList.remove('completed');
        } else if (!lastEpochSelected && !hasOtherSelection) {
            button.disabled = true;
            button.classList.remove('completed');
        }
    }

    // 工具函数：创建指标项
    function createMetricItem(abbr, fullName, value) {
        return `
            <div class="metric-item">
                <div class="metric-title">${abbr} (${fullName})</div>
                <div class="metric-value">${value}</div>
            </div>
        `;
    }

    // 切换结果显示
    function toggleFileResults(element) {
        const isExpanded = element.getAttribute('data-expanded') === 'true';
        const resultsContainer = element.nextElementSibling;
        const indicator = element.querySelector('.toggle-indicator');

        resultsContainer.style.display = isExpanded ? 'none' : 'block';
        element.setAttribute('data-expanded', !isExpanded);
        indicator.textContent = isExpanded ? '▼' : '▲';
    }
</script>
</body>
</html>